<?php

class Router
{
	private $DF;
	private $path;
	private $args = array();
	
	function __construct ( $DF )
	{
		$this->DF = $DF;
	}     

	function setPath ( $path )
	{
		# Make sure the path is a valid directory on the server
		if ( is_dir ( $path ) == false )
		{
			throw new Exception ( 'Invalid controller path: `' . $path . '`' );
		}
		
		# Set the path
		$this->path = $path;
	}
	
	#---
	function delegate ( )
	{
		# Analyze and parse the route
		$this->getController ( $file, $controller, $action, $args );
		
		# Is the derived file containing the class available?
		if ( is_readable ( $file ) == false )
		{
			# Die with 404. We can put a custom 404 trigger here if we want.
			die ( '404 Not Found: ' . $file );
		}

		# Include the file
		include ( $file );

		# Instantiate the class
		$class = 'Controller_' . $controller;
		
		$controller = new $class ( $this->DF );

		# Make sure the action is available
		if ( is_callable ( array ( $controller, $action ) ) == false )
		{
			# If the action was not available to call, trigger a 404.
			##@me:I went ahead and tried to call the index action here
			#####:This will easily allow for somethign like mysite.com/search/texas/arlington
			#####: - with texas and arlington being arguments for the search index controller
			#####:If I change my mind about this I'll just trigger a 404 right here.
			$action = 'index';
			
			if ( is_callable ( array ( $controller, $action ) ) == false )
			{
				die ( '404 Not Found 1' );
			}
		}
		
		# Run action
		$controller->$action ( $args );
		#$controller->$action ( "[Controller: " . $class . "] [Method: " . $action . "] [Controller Path: " . $file . "] [Arguments: " . implode ( ",", $args ) . "]", implode ( ",", $args ) );
	}

	#--- 
	private function getController ( &$file, &$controller, &$action, &$args ) 
	{
		$route = ( empty ( $_GET['df'] ) ) ? '' : $_GET['df'];
		
		# If there is no route set, then default to the site index controller
		if ( empty ( $route ) )
		{ 
			$route = 'index'; 
		}

		# Get separate parts of the route
		$route = trim ( $route, '/\\' );
		
		$parts = explode ( '/', $route );
		
		# Find right controller
		$cmd_path = $this->path;
		
		foreach ( $parts as $part )
		{
			$fullpath = $cmd_path . $part;
						 
			# Is there a dir with this path?
			if ( is_dir ( $fullpath ) )
			{
					$cmd_path .= $part . DIRSEP;
					
					array_shift ( $parts );
					
					continue;
			}
		
			# Find the file
			if ( is_file ( $fullpath . '.controller.php' ) )
			{
				$controller = $part;
				
				##@me:I'm oommenting this out for now because I want everything after the controller to have
				#####:the opportunity to be an argument. i.e. mysite.com/search/texas/arlington 
				#####:texas and arlington would be arguments for the index action of the search controller
				array_shift ( $parts );
				
				break;
			}
		}
		
		# If a valid controller was not derived from the route, we need to trigger a 404 or something
		if ( empty ( $controller ) ) 
		{
			$controller = 'index';
			#die ( '404 Not Found 2' . print_r($_REQUEST, true) );
		}
		
		# If a valid action could not be derived, use the index. All DF controllers are required to have an index method
		if ( empty( $parts ) ) 
		{ 
			$action = 'index'; 
		}
		else
		{
			# Get action
			$action = $parts[0];
		}
		
		# Build the full path to the controller
		$file = $cmd_path . $controller . '.controller.php';
		
		# Everything left in the parts array is an argument for the controller method/action
		$args = $parts;
		
		#>>>>DEBUGGING
		if ( _DEBUG_ )
		{
			echo "__Successfully routed request to controller: " . $file . " with arguments: " . print_r($args, TRUE) . "<br>";
		}
	}
}
?>